using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using HslCommunication;
using HslCommunicationEx.HslNet;
using HslCommunicationEx.TypesEx;
using LambdaBuilder.Resolver;
using Newtonsoft.Json;
using Catastrophe.Common;
using Catastrophe.Common.AttributeEx;
using Catastrophe.Common.Http;
using RestSharp;

namespace HslCommunicationEx.PeanutNC.Siemens
{
	public class SiePeanutClient : BaseNetDeviceOpr
	{
		private string _serverIp = "";

		private int _port = 8016;

		public string ServerIp
		{
			get
			{
				return this._serverIp;
			}
			set
			{
				this._serverIp = value;
			}
		}

		public int Port
		{
			get
			{
				return this._port;
			}
			set
			{
				this._port = value;
			}
		}

		public int ReadTimeout { get; set; } = 30000;


		public int WriteTimeout { get; set; } = 30000;


		public SiePeanutClient(string serverIp, int port = 8016)
		{
			this._serverIp = serverIp;
			this._port = port;
		}

		public override DataTable CreateDsSchema<T>()
		{
			return base.CreateDsSchema<T, ComDataAttribute>();
		}

		public override Tuple<T, OperateResult> ReadEntityMuti<T>(T dstT)
		{
			var list = (from x in typeof(T).GetProperties()
				select new
				{
					Property = x,
					CapComAb = (Attribute.GetCustomAttribute(x, typeof(CapComDataAttribute)) as CapComDataAttribute)
				} into x
				where x.CapComAb != null && x.CapComAb.OprType == OprTypeEnum.Read
				select x).ToList();
			OperateResult operateResult = new OperateResult();
			OperateResult<string> operateResult2 = this.Read(list.Select(x => x.CapComAb.Adr).ToArray());
			if (!operateResult2.IsSuccess)
			{
				operateResult.Message = operateResult2.Message;
				return new Tuple<T, OperateResult>(dstT, operateResult);
			}
			GOperateRet<Dictionary<string, string>> gOperateRet = JsonConvert.DeserializeObject<GOperateRet<Dictionary<string, string>>>(operateResult2.Content);
			if (!gOperateRet.Success)
			{
				operateResult.Message = gOperateRet.Message;
				return new Tuple<T, OperateResult>(dstT, operateResult);
			}
			foreach (var item in list)
			{
				if (gOperateRet.Content.ContainsKey(item.CapComAb.Adr))
				{
					DataConverter.PropertySetValue(dstT, item.Property, gOperateRet.Content[item.CapComAb.Adr]);
				}
			}
			operateResult.IsSuccess = true;
			return new Tuple<T, OperateResult>(dstT, operateResult);
		}

		public override OperateResult ReadSingle<T>(string filedName, ushort len = 0)
		{
			if (filedName == null)
			{
				throw new ArgumentNullException("filedName");
			}
			OperateResultEx<string> operateResultEx = new OperateResultEx<string>();
			PropertyInfo propertyInfo = typeof(T).GetProperties().FirstOrDefault((PropertyInfo x) => x.Name.Equals(filedName));
			if (propertyInfo == null)
			{
				operateResultEx.Message = "目标属性不存在";
				return operateResultEx;
			}
			CapComDataAttribute capComDataAttribute = Attribute.GetCustomAttribute(propertyInfo, typeof(CapComDataAttribute)) as CapComDataAttribute;
			if (capComDataAttribute == null)
			{
				operateResultEx.Message = "缺少特性修饰CapComDataAttribute";
				return operateResultEx;
			}
			if (capComDataAttribute.OprType != OprTypeEnum.Read)
			{
				operateResultEx.Message = "未标记Read";
				return operateResultEx;
			}
			OperateResult<string> operateResult = this.Read(capComDataAttribute.Adr);
			if (!operateResult.IsSuccess)
			{
				operateResultEx.Message = operateResult.Message;
				return operateResultEx;
			}
			GOperateRet<Dictionary<string, string>> gOperateRet = JsonConvert.DeserializeObject<GOperateRet<Dictionary<string, string>>>(operateResult.Content);
			if (!gOperateRet.Success)
			{
				operateResultEx.Message = gOperateRet.Message;
				return operateResultEx;
			}
			operateResultEx.IsSuccess = true;
			operateResultEx.Content = gOperateRet.Content.Values.First();
			return operateResultEx;
		}

		public override OperateResult WriteEntityMuti<T>(T entity, Expression<Func<T, object>> exp, ushort attempTimes = 0, ushort attempInterval = 30)
		{
			List<string> filedName = LambdaResolver.GetColumnNames(exp);
			if (filedName.Count == 0)
			{
				throw new Exception("目标地址不存在！");
			}
			var list = (from x in typeof(T).GetProperties()
				select new
				{
					Property = x,
					CapComAb = (Attribute.GetCustomAttribute(x, typeof(CapComDataAttribute)) as CapComDataAttribute)
				} into x
				where x.CapComAb != null && x.CapComAb.OprType == OprTypeEnum.Write && filedName.Contains(x.Property.Name)
				select x).ToList();
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			foreach (var item in list)
			{
				object value = item.Property.GetValue(entity);
				if (!dictionary.ContainsKey(item.CapComAb.Adr))
				{
					dictionary.Add(item.CapComAb.Adr, value);
				}
			}
			return this.Write(dictionary);
		}

		public override OperateResult WriteEntitySingle<T>(string filedName, dynamic value, ushort attempTimes = 0, ushort attempInterval = 30)
		{
			return WriteEntitySingle(typeof(T), filedName, value, attempTimes, attempInterval);
		}

		public override OperateResult WriteEntitySingle(Type entityType, string filedName, dynamic value, ushort attempTimes = 0, ushort attempInterval = 30)
		{
			if ((object)entityType == null)
			{
				throw new ArgumentNullException("entityType");
			}
			if (string.IsNullOrEmpty(filedName))
			{
				return new OperateResult
				{
					IsSuccess = false,
					Message = "字段名称不能为空"
				};
			}
			PropertyInfo property = entityType.GetProperty(filedName);
			CapComDataAttribute capComDataAttribute = Attribute.GetCustomAttribute(property ?? throw new InvalidOperationException(), typeof(CapComDataAttribute)) as CapComDataAttribute;
			if (capComDataAttribute == null)
			{
				return new OperateResult
				{
					IsSuccess = false,
					Message = "当前属性未标记ComDataAttribute"
				};
			}
			if (string.IsNullOrWhiteSpace(capComDataAttribute.Adr))
			{
				return new OperateResult
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "地址为空！"
				};
			}
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			dictionary.Add(capComDataAttribute.Adr, value);
			return this.Write(dictionary);
		}

		public OperateResult<string> Read(params string[] adrBuf)
		{
			if (adrBuf == null)
			{
				throw new ArgumentNullException("adrBuf");
			}
			OperateResult<string> operateResult = new OperateResult<string>
			{
				Message = ""
			};
			if (adrBuf.Length == 0)
			{
				operateResult.Message = "adr length=0";
				return operateResult;
			}
			StringBuilder stringBuilder = new StringBuilder("[");
			foreach (string value in adrBuf)
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2);
				handler.AppendLiteral("\"");
				handler.AppendFormatted(value);
				handler.AppendLiteral("\",");
				stringBuilder2.Append(ref handler);
			}
			string value2 = stringBuilder.Remove(stringBuilder.Length - 1, 1).Append("]").ToString();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary.Add("Custom-Param1", value2);
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(45, 3);
			defaultInterpolatedStringHandler.AppendLiteral("http://");
			defaultInterpolatedStringHandler.AppendFormatted(this._serverIp);
			defaultInterpolatedStringHandler.AppendLiteral(":");
			defaultInterpolatedStringHandler.AppendFormatted(this._port);
			defaultInterpolatedStringHandler.AppendLiteral("/CapService/CapSyncReadMulti?timeout=");
			defaultInterpolatedStringHandler.AppendFormatted(this.ReadTimeout);
			RestResponse restResponse = HttpUtil.RequestBehaviorSync(defaultInterpolatedStringHandler.ToStringAndClear(), Method.Get, "", isToken: true, isJson: true, keepAlive: true, dictionary, this.ReadTimeout);
			if (!restResponse.IsSuccessful)
			{
				operateResult.Message = restResponse.ErrorMessage;
				return operateResult;
			}
			operateResult.IsSuccess = true;
			operateResult.Content = restResponse.Content;
			return operateResult;
		}

		public OperateResult Write(Dictionary<string, object> dic)
		{
			if (dic == null)
			{
				throw new ArgumentNullException("dic");
			}
			OperateResult operateResult = new OperateResult
			{
				Message = ""
			};
			if (dic.Count == 0)
			{
				operateResult.Message = "dic length=0";
				return operateResult;
			}
			string value = JsonConvert.SerializeObject(dic);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary.Add("Custom-Param1", value);
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(46, 3);
			defaultInterpolatedStringHandler.AppendLiteral("http://");
			defaultInterpolatedStringHandler.AppendFormatted(this._serverIp);
			defaultInterpolatedStringHandler.AppendLiteral(":");
			defaultInterpolatedStringHandler.AppendFormatted(this._port);
			defaultInterpolatedStringHandler.AppendLiteral("/CapService/CapSyncWriteMulti?timeout=");
			defaultInterpolatedStringHandler.AppendFormatted(this.WriteTimeout);
			RestResponse restResponse = HttpUtil.RequestBehaviorSync(defaultInterpolatedStringHandler.ToStringAndClear(), Method.Get, "", isToken: true, isJson: true, keepAlive: true, dictionary, this.WriteTimeout);
			if (!restResponse.IsSuccessful)
			{
				operateResult.Message = restResponse.ErrorMessage;
				return operateResult;
			}
			OperateRet operateRet = JsonConvert.DeserializeObject<OperateRet>(restResponse.Content);
			operateResult.IsSuccess = operateRet.Success;
			operateResult.Message = operateRet.Message;
			return operateResult;
		}
	}
}
